package com.pureut.order.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.pureut.order.domain.ProcurementPlan;
import com.pureut.order.domain.ProcurementPlanBack;
import com.pureut.order.domain.ProcurementPlanDetail;
import com.pureut.order.dto.ProcurementPlanDto;
import com.pureut.order.mapper.ProcurementPlanBackMapper;
import com.pureut.order.mapper.ProcurementPlanMapper;
import com.pureut.order.service.ProcurementPlanBackService;
import com.pureut.order.service.ProcurementPlanDetailService;
import com.pureut.order.service.ProcurementPlanService;
import com.pureut.order.service.PurchaseOrderService;
import com.pureut.order.vo.*;
import com.sale.common.core.constant.CacheNames;
import com.sale.common.core.exception.GlobalException;
import com.sale.common.mybatis.core.page.PageQuery;
import com.sale.common.mybatis.core.page.TableDataInfo;
import com.sale.common.redis.utils.CacheUtils;
import com.sale.common.redis.utils.RedisUtils;
import com.sale.common.satoken.utils.LoginHelper;
import com.sale.system.api.*;
import com.sale.system.api.domain.SysAuxiliary;
import com.sale.system.api.domain.SysDictData;
import com.sale.system.api.domain.dto.SysCustomDto;
import com.sale.system.api.domain.vo.SysAuditHistoryVo;
import com.sale.system.api.domain.vo.SysWorkbenchAuditAgentDubboVo;
import lombok.RequiredArgsConstructor;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.fasterxml.jackson.core.type.TypeReference;


import java.io.Serializable;
import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 采购计划实现层
 */
@RequiredArgsConstructor
@Service
public class ProcurementPlanServiceImpl implements ProcurementPlanService {


    private final ProcurementPlanMapper procurementPlanMapper;


    @Lazy
    ProcurementPlanDetailService procurementPlanDetailService;

    private final ProcurementPlanBackService procurementPlanBackService;


    private final ProcurementPlanBackMapper procurementPlanBackMapper;

    @DubboReference
    private final RemoteCodeService remoteCodeService;

    @DubboReference
    private final RemoteReviewService remoteReviewService;

    @DubboReference
    RemoteWorkbenchMessageService remoteWorkbenchMessageService;


    private final PurchaseOrderService purchaseOrderService;

    @DubboReference
    RemoteUnitService remoteUnitService;

    @DubboReference
    RemoteStaffManagementService remoteStaffManagementService;

    /**
     * 采购计划列表
     *
     * @param procurementPlanVo
     * @return
     */
    @Override
    public TableDataInfo<Map<String, Object>> getList(ProcurementPlanVo procurementPlanVo, PageQuery pageQuery) {
        //状态
        List<SysDictData> statusArray = CacheUtils.get(CacheNames.SYS_DICT, "procurement_plan_status");
        Map<String, String> statusMap = statusArray.stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel));
        //表名
        String tableName = "`ry-order`.procurement_plan";
        //通过缓存获取自定义表头信息
        String userIdStr = LoginHelper.getUserIdStr();
        String tenantId = RedisUtils.getCacheObject(userIdStr);
        List<SysCustomDto> titleMessage = CacheUtils.get(CacheNames.SYS_CUSTOM + "_" + tenantId, tableName);
        StringBuilder stringBuilder = new StringBuilder();
        String code = "";
        Page<Map<String, Object>> procurementPlanDtoPage = null;
        if (titleMessage != null) {
            for (SysCustomDto entity : titleMessage) {
                stringBuilder.append(",").append("a.").append(entity.getFieldsModel());
            }
            code = stringBuilder.toString();
            procurementPlanDtoPage = procurementPlanMapper.getprocurementPlanList(code, pageQuery.build(), procurementPlanVo);
        } else {
            procurementPlanDtoPage = procurementPlanMapper.getprocurementPlanList(code, pageQuery.build(), procurementPlanVo);
        }

        List<Map<String, Object>> list = procurementPlanDtoPage.getRecords();

        for (Map<String, Object> map : list) {
            //物料类别
            if ("1".equals(map.get("materialCategoryDict"))) {
                map.put("materialCategoryDict", "原料");
            } else {
                map.put("materialCategoryDict", "成品");
            }
            //辅助属性
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + map.get("tenantId").toString(), String.valueOf(map.get("materialId")));
            map.put("auxiliaryAttribute", statsArray);
            //采购计划状态
            map.put("statusDict", statusMap.get(map.get("status").toString()));
            //单位
            if (map.get("unit") != null) {
                String unit = remoteUnitService.getUnitDataByCode(Long.parseLong((String) map.get("unit"))).getData().getUnitName();
                map.put("unitDict", unit);
            }
            //计划人
            String demander = remoteStaffManagementService.getInfo(Long.parseLong((String) map.get("demander"))).getData().getStaffName();
            map.put("demanderDict", demander);
        }

//        for (ProcurementPlanDto entity : records) {
//            //物料类别
//            if ("1".equals(entity.getMaterialCategory())) {
//                entity.setMaterialCategoryDict("原料");
//            } else {
//                entity.setMaterialCategoryDict("成品");
//            }
//            //辅助属性
//            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + entity.getTenantId(), String.valueOf(entity.getMaterialId()));
//            entity.setAuxiliaryAttribute(statsArray);
//            //采购计划状态
//            entity.setStatusDict(statusMap.get(entity.getStatus()));
//            //单位
//            if (entity.getUnit() != null) {
//                entity.setUnitDict(remoteUnitService.getUnitDataByCode(Long.parseLong(entity.getUnit())).getData().getUnitName());
//            }
//            //计划人
//            entity.setDemanderDict(remoteStaffManagementService.getInfo(Long.parseLong(entity.getDemander())).getData().getStaffName());
//        }
        return TableDataInfo.build(procurementPlanDtoPage);
    }

    /**
     * 新增采购计划
     *
     * @param map
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean addProcurementPlan(Map<String, Object> map) throws Exception {
        Object materialList1 = map.get("materialList");
        ObjectMapper objectMapper = new ObjectMapper();
        String jsonString = objectMapper.writeValueAsString(materialList1);
        List<MaterialVo> materialList = JSON.parseArray(jsonString, MaterialVo.class);
//        List<MaterialVo> materialList = procurementPlanVo.getMaterialList();
//        List<ProcurementPlan> procurementPlanList = new ArrayList<>();
        //表名
        String tableName = "`ry-order`.procurement_plan";
        //通过缓存获取自定义表头信息
        String userIdStr = LoginHelper.getUserIdStr();
        String tenantId = RedisUtils.getCacheObject(userIdStr);
        List<SysCustomDto> titleMessage = CacheUtils.get(CacheNames.SYS_CUSTOM + "_" + tenantId, tableName);
        StringBuilder stringBuilder = new StringBuilder();
        String code = "";
        if (titleMessage != null) {
            for (SysCustomDto entity : titleMessage) {
                stringBuilder.append(",").append(entity.getFieldsModel());
            }
            code = stringBuilder.toString();
        }
        Map<String, Object> addMap = new LinkedHashMap<>();
        for (MaterialVo entity : materialList) {
//            ProcurementPlan procurementPlan = new ProcurementPlan();
            String authorityCoding = remoteCodeService.authorityCoding("order:purchase:plan:list");
            if (authorityCoding == null) {
                throw new GlobalException("未进行单据配置,单据编码生成失败");
            }

            addMap.put("purchaseNum", authorityCoding);
            addMap.put("deptId", LoginHelper.getDeptId());
            addMap.put("status", 1);
            addMap.put("materialId", entity.getMaterialId());
            addMap.put("materialCode", entity.getMaterialCode());
            addMap.put("planWeight", entity.getPlanWeight());
            addMap.put("materialCategory", map.get("materialCategory"));
            addMap.put("remark", map.get("remark"));
            addMap.put("unit", entity.getUnit());
            addMap.put("createBy", LoginHelper.getUsername());
            addMap.put("demander", map.get("demander"));
            addMap.put("createTime", new Date());
            addMap.put("qualityStandard", 1);
            addMap.put("demandTime", entity.getDemandTime());
            if (titleMessage != null) {
                for (SysCustomDto entity1 : titleMessage) {
                    addMap.put(entity1.getFieldsModel(), map.get(entity1.getFieldsModel()));
                }
            }
    /*        if (titleMessage != null) {
                for (SysCustomDto entity1 : titleMessage) {
                    for (Map.Entry<String, Object> entry : map.entrySet()) {
                        if (entity1.getFieldsModel().equals(entry.getKey())) {
                            addMap.put(entry.getKey(),entry.getValue());
                            break;
                        }
                    }
                }
            }*/

//            procurementPlan.setPurchaseNum(authorityCoding)
//                .setDeptId(LoginHelper.getDeptId())
//                .setStatus(1)
//                .setMaterialCode(entity.getMaterialCode())
//                .setPlanWeight(entity.getPlanWeight())
//                .setMaterialCategory(Integer.parseInt(procurementPlanVo.getMaterialCategory()))
////                .setDemandDept(Long.parseLong(procurementPlanVo.getDemandDept()))
//                .setRemark(procurementPlanVo.getRemark())
//                .setEnclosureUrl(procurementPlanVo.getEnclosureUrl())
//                .setUnit(entity.getUnit())
//                .setCreateBy(LoginHelper.getUsername())
//                .setDemander(procurementPlanVo.getDemander())
//                .setCreateTime(new Date())
//                .setQualityStandard(entity.getQualityStandard())
//                .setDemandTime(entity.getDemandTime());
        }
        return procurementPlanMapper.insertMessage(code, addMap);
//        return procurementPlanMapper.insertBatch(procurementPlanList);

    }

    /**
     * 修改采购计划
     *
     * @param map
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateProcurementPlan(Map<String, Object> map) throws JsonProcessingException {

        Long id = Long.valueOf(map.get("id").toString());
        ProcurementPlan procurementPlan = procurementPlanMapper.selectById(id);
        if (1 == procurementPlan.getStatus() || 4 == procurementPlan.getStatus()) {
            //表名
            String tableName = "`ry-order`.procurement_plan";
            //通过缓存获取自定义表头信息
            String userIdStr = LoginHelper.getUserIdStr();
            String tenantId = RedisUtils.getCacheObject(userIdStr);
            List<SysCustomDto> titleMessage = CacheUtils.get(CacheNames.SYS_CUSTOM + "_" + tenantId, tableName);
//            StringBuilder stringBuilder = new StringBuilder();
//            String code = "";
//            if (titleMessage != null) {
//                for (SysCustomDto entity : titleMessage) {
//                    stringBuilder.append(",").append(entity.getFieldsModel());
//                }
//                code = stringBuilder.toString();
//            }
            Object materialList1 = map.get("materialList");
            ObjectMapper objectMapper = new ObjectMapper();
            String jsonString = objectMapper.writeValueAsString(materialList1);
            List<PlanUpdateVo> planList = JSON.parseArray(jsonString, PlanUpdateVo.class);

            Map<String, Object> updateMap = new LinkedHashMap<>();
//            List<PlanUpdateVo> planList = procurementPlanUpdateVo.getMaterialList();
            for (PlanUpdateVo entity : planList) {
                updateMap.put("plan_weight", entity.getPlanWeight());
                updateMap.put("unit", entity.getUnit());
                updateMap.put("demand_time", entity.getDemandTime());
                updateMap.put("material_code", entity.getMaterialCode());
                updateMap.put("material_id", entity.getMaterialId());
//                procurementPlan.setPlanWeight(entity.getPlanWeight());
//                procurementPlan.setUnit(entity.getUnit());
//                procurementPlan.setDemandTime(entity.getDemandTime());
//                procurementPlan.setMaterialCode(entity.getMaterialCode());
            }
            updateMap.put("remark", map.get("remark"));
            updateMap.put("enclosure_url", map.get("enclosureUrl"));
            updateMap.put("demander", map.get("demander"));
            if (titleMessage != null) {
                for (SysCustomDto entity1 : titleMessage) {
                    updateMap.put(entity1.getFieldsModel(), map.get(entity1.getFieldsModel()));
                }
            }
//            procurementPlan.setRemark(procurementPlanUpdateVo.getRemark());
//            procurementPlan.setEnclosureUrl(procurementPlanUpdateVo.getEnclosureUrl());
//            procurementPlan.setDemander(procurementPlanUpdateVo.getDemander());


            //调用审核
            if (procurementPlan.getStatus() == 4) {
                SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
                String perms = "order:purchase:plan:review";
                String auditDoc = procurementPlan.getPurchaseNum();
                sysAuditHistoryVo.setAuditDoc(auditDoc);
                sysAuditHistoryVo.setPerms(perms);
                int i = remoteReviewService.editHistory(sysAuditHistoryVo);
                if (i > 0) {
                    procurementPlan.setStatus(2);
//                    //修改审核代办状态为已处理
//                    feignService.updateStatus(3,procurementPlan.getPurchaseNum(),"采购计划");
                    return procurementPlanMapper.updateById(procurementPlan) > 0;
                } else {
                    return false;
                }
            }
            return procurementPlanMapper.updateProcurementPlan(id, updateMap);
        } else {
            throw new GlobalException("不属于待提交和未通过的采购计划");
        }
    }

    /**
     * 提交审核
     *
     * @param id
     * @return
     */
    @Override
    public boolean submitReview(Long id) {
        ProcurementPlan procurementPlan = procurementPlanMapper.selectById(id);
        if (1 == procurementPlan.getStatus()) {
            procurementPlan.setStatus(2);

            SysWorkbenchAuditAgentDubboVo sysWorkbenchAuditAgentDubboVo = new SysWorkbenchAuditAgentDubboVo();
            sysWorkbenchAuditAgentDubboVo.setDocConfig("order:purchase:plan:review");
            sysWorkbenchAuditAgentDubboVo.setReceiptName("采购计划");
            sysWorkbenchAuditAgentDubboVo.setReceiptNumber(procurementPlan.getPurchaseNum());//采购计划单号
            sysWorkbenchAuditAgentDubboVo.setStatus(1);//待审核
            sysWorkbenchAuditAgentDubboVo.setReceiptContent("有单据待审核,请及时审核");

            remoteWorkbenchMessageService.insertAuditAgent(sysWorkbenchAuditAgentDubboVo);

            return procurementPlanMapper.updateById(procurementPlan) > 0;
        } else {
            throw new GlobalException("只能提交待审核得单据");
        }

    }

    /**
     * 撤销审核
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteReview(Long id) {
        ProcurementPlan procurementPlan = procurementPlanMapper.selectById(id);
        if (2 == procurementPlan.getStatus()) {
            procurementPlan.setStatus(1);

            //删除审核代办
            remoteWorkbenchMessageService.deleteDoc(procurementPlan.getPurchaseNum(), "采购计划");

            return procurementPlanMapper.updateById(procurementPlan) > 0;
        } else {
            throw new GlobalException("只能撤销待审核的采购计划");
        }
    }

    /**
     * 删除采购计划
     *
     * @param ids
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteProcurementPlan(String ids) {
        List<String> idList = Arrays.asList(ids.split(","));
        List<ProcurementPlan> procurementPlan = procurementPlanMapper.selectList(new QueryWrapper<ProcurementPlan>().lambda().in(ProcurementPlan::getId, idList));
        List<ProcurementPlan> procurementPlanList = new ArrayList<>();
        for (ProcurementPlan entity : procurementPlan) {
            if (1 == entity.getStatus() || 4 == entity.getStatus()) {
                procurementPlanList.add(entity);

                remoteWorkbenchMessageService.deleteDoc(entity.getPurchaseNum(), "采购计划");

            } else {
                throw new GlobalException("只能删除待提交或者未通过的采购计划");
            }
        }
        return procurementPlanMapper.deleteBatchIds(procurementPlanList) > 0;
    }

    /**
     * 撤回采购计划
     *
     * @param id
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean backPlan(Long id) throws SQLException {
        ProcurementPlanDetail procurementPlanDetail = procurementPlanDetailService.getById(id);
        if (1 == procurementPlanDetail.getStatus()) {
            try {
                //获取撤回信息数据
                List<ProcurementPlanBack> procurementPlanBacks = procurementPlanBackMapper.selectList(new QueryWrapper<ProcurementPlanBack>().lambda().eq(ProcurementPlanBack::getDetailId, id));
                for (ProcurementPlanBack entity : procurementPlanBacks) {
                    //将之前下达的重量返还
                    ProcurementPlan procurementPlan = procurementPlanMapper.selectById(entity.getPlanId());
                    BigDecimal add = new BigDecimal(procurementPlan.getSurplusNum()).add(new BigDecimal(entity.getLowerWeight()));
                    procurementPlan.setSurplusNum(add.toString());
                    if (add.toString().equals(procurementPlan.getPlanWeight())) {
                        procurementPlan.setStatus(1);
                    } else if (Integer.parseInt(add.toString()) < Integer.parseInt(procurementPlan.getPlanWeight())) {
                        procurementPlan.setStatus(8);
                    }
                    procurementPlanMapper.updateById(procurementPlan);
                }
                //删除明细数据，同时删除对应的撤回信息数据
                procurementPlanBackService.removeBatchByIds(procurementPlanBacks);
                return procurementPlanDetailService.removeById(procurementPlanDetail);
            } catch (Exception e) {
                throw new SQLException("批量删除失败");
            }
        } else {
            throw new GlobalException("只能撤回预下单得数据");
        }

    }

    /**
     * 关结采购计划
     *
     * @param procurementPlanVo
     * @return
     */
    @Override
    public boolean closePlan(ProcurementPlanVo procurementPlanVo) {
        ProcurementPlan procurementPlan = procurementPlanMapper.selectById(procurementPlanVo.getId());
        procurementPlan.setStatus(8);
        procurementPlan.setCloseReason(procurementPlanVo.getCloseReason());
        return procurementPlanMapper.updateById(procurementPlan) > 0;
    }

    /**
     * 查看
     *
     * @param id
     * @return
     */
    @Override
    public Map<String, Object> getPlanById(Long id) {
        Map<String, Object> map = new HashMap<>();
        //表名
        String tableName = "`ry-order`.procurement_plan";
        //通过缓存获取自定义表头信息
        String userIdStr = LoginHelper.getUserIdStr();
        String tenantId = RedisUtils.getCacheObject(userIdStr);
        List<SysCustomDto> titleMessage = CacheUtils.get(CacheNames.SYS_CUSTOM + "_" + tenantId, tableName);

        Map<String, Object> viewById = procurementPlanMapper.getViewById(id);
        if (titleMessage != null) {
            for (SysCustomDto entity : titleMessage) {
                if(viewById.get(entity.getFieldsModel()) != null){
                    map.put(entity.getFieldsModel(),viewById.get(entity.getFieldsModel()));
                }
            }
        }
//        ProcurementPlanDto procurementPlanDto = new ProcurementPlanDto();

//        procurementPlanDto.setStatus(String.valueOf(viewById.getStatus()));
        map.put("status", viewById.get("status"));
        List<Map<String, Object>> materialVos = new ArrayList<>();
        Map<String, Object> materialVoMap = new HashMap<>();
//        MaterialVo materialVo = new MaterialVo();
        materialVoMap.put("materialName", viewById.get("bMaterialName"));
//        materialVo.setMaterialName(viewById.getMaterialName());
        if ("1".equals(viewById.get("materialCategory").toString())) {
            materialVoMap.put("materialCategoryDict", "原料");
//            materialVo.setMaterialCategoryDict("原料");
        } else {
            materialVoMap.put("materialCategoryDict", "成品");
//            materialVo.setMaterialCategoryDict("成品");
        }
        materialVoMap.put("materialCode", viewById.get("materialCode"));
        materialVoMap.put("materialSpec", viewById.get("materialSpec"));
        materialVoMap.put("lowerWeight", String.valueOf(viewById.get("orderQuantity")));
        materialVoMap.put("plannedUnitPrice", viewById.get("plannedUnitPrice"));
        materialVoMap.put("planWeight", viewById.get("planWeight"));
        materialVoMap.put("codingRules", viewById.get("codingRules"));
        materialVoMap.put("materialId", viewById.get("materialId"));
        materialVoMap.put("demandTime", viewById.get("demandTime"));
        materialVoMap.put("unit", viewById.get("unit"));
        materialVoMap.put("unitDict", remoteUnitService.getUnitDataByCode(Long.parseLong(viewById.get("unit").toString())).getData().getUnitName());
        materialVoMap.put("auxiliaryAttribute", CacheUtils.get(CacheNames.SYS_GINSENG + "_" + viewById.get("tenantId").toString(), String.valueOf(viewById.get("materialId"))));
        materialVos.add(materialVoMap);
//        materialVo.setMaterialCode(viewById.getMaterialCode());
//        materialVo.setMaterialSpec(viewById.getMaterialSpec());
//        materialVo.setLowerWeight(String.valueOf(viewById.getOrderQuantity()));
//        materialVo.setPlannedUnitPrice(viewById.getPlannedUnitPrice());
//        materialVo.setPlanWeight(viewById.getPlanWeight());
//        materialVo.setCodingRules(viewById.getCodingRules());
//        materialVo.setMaterialId(viewById.getMaterialId());
//        materialVo.setDemandTime(viewById.getDemandTime());
//        materialVo.setUnit(String.valueOf(viewById.getUnit()));
//        materialVo.setUnitDict(remoteUnitService.getUnitDataByCode(Long.parseLong(viewById.getUnit())).getData().getUnitName());
        //获取辅助属性
//        List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + viewById.getTenantId(), String.valueOf(viewById.getMaterialId()));
//        materialVo.setAuxiliaryAttribute(statsArray);

//        materialVos.add(materialVo);
        map.put("materialList", materialVos);
//        procurementPlanDto.setMaterialList(materialVos);
        map.put("purchaseNum", viewById.get("purchaseNum"));
//        procurementPlanDto.setPurchaseNum(viewById.getPurchaseNum());
        map.put("demandDept", viewById.get("demandDept"));
//        procurementPlanDto.setDemandDept(String.valueOf(viewById.getDemandDept()));
        map.put("remark", viewById.get("remark"));
//        procurementPlanDto.setRemark(viewById.getRemark());
        map.put("enclosureUrl", viewById.get("enclosureUrl"));
//        procurementPlanDto.setEnclosureUrl(viewById.getEnclosureUrl());
        map.put("closeReason", viewById.get("closeReason"));
//        procurementPlanDto.setCloseReason(viewById.getCloseReason());
        map.put("id", viewById.get("id"));
//        procurementPlanDto.setId(viewById.getId());
        map.put("demanderDict", remoteStaffManagementService.getInfo(Long.parseLong(viewById.get("demander").toString())).getData().getStaffName());
//        procurementPlanDto.setDemanderDict(remoteStaffManagementService.getInfo(Long.parseLong(viewById.getDemander())).getData().getStaffName());
        map.put("demander", viewById.get("demander"));
//        procurementPlanDto.setDemander(viewById.getDemander());
        return map;
    }

    /**
     * 审核单据
     *
     * @param orderReviewVo
     * @return
     */
    @Override
    public boolean purchaseReview(OrderReviewVo orderReviewVo) throws Exception {
        ProcurementPlan procurementPlan = procurementPlanMapper.selectById(orderReviewVo.getId());
        if (procurementPlan.getStatus() == 2 || procurementPlan.getStatus() == 3) {
            String perms = "order:purchase:plan:review";
            int isAdopt = orderReviewVo.getIsAdopt();
            String auditDoc = procurementPlan.getPurchaseNum();
            String auditRemarks = orderReviewVo.getReviewComments();
            Long userId = LoginHelper.getUserId();
            SysAuditHistoryVo sysAuditHistoryVo = new SysAuditHistoryVo();
            sysAuditHistoryVo.setPerms(perms);
            sysAuditHistoryVo.setAuditType(2);
            sysAuditHistoryVo.setAuditState(isAdopt);
            sysAuditHistoryVo.setAuditRemarks(auditRemarks);
            sysAuditHistoryVo.setAuditDoc(auditDoc);
            sysAuditHistoryVo.setUserId(userId);
            int data = remoteReviewService.getSequence(sysAuditHistoryVo);
            if (data == 0) {
                throw new GlobalException("未对该审核进行配置");
            }
            //1:通过，2：审核中，3：没权限 4:该人已经审核过
            if (orderReviewVo.getIsAdopt() == 1) {
                if (data == 1) {
                    procurementPlan.setStatus(5);
                    if (procurementPlan.getReviewBy() == null) {
                        procurementPlan.setReviewBy(LoginHelper.getUsername());
                    } else {
                        procurementPlan.setReviewBy(procurementPlan.getReviewBy() + "," + LoginHelper.getUsername());
                    }
                    procurementPlan.setReviewTime(new Date());

                    remoteWorkbenchMessageService.updateStatus(3, procurementPlan.getPurchaseNum(), "采购计划");

                    return procurementPlanMapper.updateById(procurementPlan) > 0;
                } else if (data == 2) {
                    procurementPlan.setStatus(3);
                    if (procurementPlan.getReviewBy() == null) {
                        procurementPlan.setReviewBy(LoginHelper.getUsername());
                    } else {
                        procurementPlan.setReviewBy(procurementPlan.getReviewBy() + "," + LoginHelper.getUsername());
                    }
                    procurementPlan.setReviewTime(new Date());
                    return procurementPlanMapper.updateById(procurementPlan) > 0;
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            } else {
                if (data == 1 || data == 2) {
                    procurementPlan.setStatus(4);
                    if (procurementPlan.getReviewBy() == null) {
                        procurementPlan.setReviewBy(LoginHelper.getUsername());
                    } else {
                        procurementPlan.setReviewBy(procurementPlan.getReviewBy() + "," + LoginHelper.getUsername());
                    }

                    SysWorkbenchAuditAgentDubboVo sysWorkbenchAuditAgentDubboVo = new SysWorkbenchAuditAgentDubboVo();
                    sysWorkbenchAuditAgentDubboVo.setDocConfig("order:purchase:plan:review");
                    sysWorkbenchAuditAgentDubboVo.setReceiptName("采购计划");
                    sysWorkbenchAuditAgentDubboVo.setReceiptNumber(procurementPlan.getPurchaseNum());//采购需求单号
                    sysWorkbenchAuditAgentDubboVo.setStatus(2);//待处理

                    sysWorkbenchAuditAgentDubboVo.setPassFlag("1");
                    sysWorkbenchAuditAgentDubboVo.setCreateName(procurementPlan.getCreateBy());

                    sysWorkbenchAuditAgentDubboVo.setReceiptContent("有单据未通过,请及时查看");

                    remoteWorkbenchMessageService.insertAuditAgent(sysWorkbenchAuditAgentDubboVo);

                    procurementPlan.setReviewTime(new Date());
                    return procurementPlanMapper.updateById(procurementPlan) > 0;
                } else if (data == 3) {
                    throw new GlobalException("没有审核权限");
                } else {
                    throw new GlobalException("该用户已经审核过");
                }
            }
        } else {
            throw new GlobalException("状态为“待合同审核”和“合同审核中”的单据才能进行审核");
        }
    }

    /**
     * 计划下达数据回显
     *
     * @param ids
     * @return
     */
    @Override
    public List<ProcurementPlanDto> planReleaseView(String ids) {
        List<String> idList = Arrays.asList(ids.split(","));
        if (idList.size() == 0) {
            throw new GlobalException("请至少选择一条数据");
        }
        List<ProcurementPlanDto> procurementPlanListByIds = procurementPlanMapper.getProcurementPlanListByIds(idList);
        for (ProcurementPlanDto entity : procurementPlanListByIds) {
            //单位
            entity.setUnitDict(remoteUnitService.getUnitDataByCode(Long.parseLong(entity.getUnit())).getData().getUnitName());
            //辅助属性
            List<SysAuxiliary> statsArray = CacheUtils.get(CacheNames.SYS_GINSENG + "_" + entity.getTenantId(), String.valueOf(entity.getMaterialId()));
            entity.setAuxiliaryAttribute(statsArray);
            //类别
            if ("1".equals(entity.getMaterialCategory())) {
                entity.setMaterialCategoryDict("原料");
            } else {
                entity.setMaterialCategoryDict("成品");
            }
        }
        return procurementPlanListByIds;
    }

    /**
     * 计划下达
     *
     * @param planReleaseVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean planRelease(PlanReleaseVo planReleaseVo) throws Exception {
        List<PlanVo> planList = planReleaseVo.getPlanList();
        if (planList.size() == 1) {
            PlanVo planVo = planList.get(0);
            //修改计划单状态
            ProcurementPlan procurementPlan = procurementPlanMapper.selectById(planVo.getPlanId());
            if (procurementPlan.getStatus() != 5 && procurementPlan.getStatus() != 6) {
                throw new GlobalException("只能操作待下达或者下达中的单据");
            }

            BigDecimal surplusNum;
            if (procurementPlan.getSurplusNum() == null) {
                surplusNum = new BigDecimal(procurementPlan.getPlanWeight()).subtract(new BigDecimal(planVo.getLowerWeight()));
            } else {
                surplusNum = new BigDecimal(procurementPlan.getSurplusNum()).subtract(new BigDecimal(planVo.getLowerWeight()));
            }
            if (Integer.parseInt(surplusNum.toString()) > 0) {
                procurementPlan.setStatus(6);
            } else {
                procurementPlan.setStatus(7);
            }
            procurementPlan.setSurplusNum(surplusNum.toString());

            if (Integer.parseInt(planReleaseVo.getLowerWeightTotal()) >= Integer.parseInt(planVo.getLowerWeight())) {
                procurementPlan.setPlannedUnitPrice(planReleaseVo.getPlannedUnitPrice());
                if (procurementPlan.getOrderQuantity() == 0) {
                    procurementPlan.setOrderQuantity(Double.parseDouble(planVo.getLowerWeight()));
                } else {
                    BigDecimal bigDecimal = new BigDecimal(String.valueOf(procurementPlan.getOrderQuantity()));
                    BigDecimal bigDecimalPlanVo = new BigDecimal(planVo.getLowerWeight());
                    BigDecimal add = bigDecimal.add(bigDecimalPlanVo);
                    procurementPlan.setOrderQuantity(Double.parseDouble(add.toString()));
                }
                procurementPlan.setOrderQuantity(Double.parseDouble(planVo.getLowerWeight()));
                procurementPlanMapper.updateById(procurementPlan);
            } else {
                throw new GlobalException("下达总重量应大于等于分重量之和");
            }
            //存入采购订单
            PurchaseOrderVo purchaseOrderVo = new PurchaseOrderVo();
            purchaseOrderVo.setMaterialCode(procurementPlan.getMaterialCode());
            purchaseOrderVo.setPurchaseNum(procurementPlan.getPurchaseNum());
            purchaseOrderVo.setPlannedUnitPrice(planReleaseVo.getPlannedUnitPrice());
            purchaseOrderVo.setActualWeight(planVo.getLowerWeight());
            purchaseOrderVo.setMaterialCode(procurementPlan.getMaterialCode());
            purchaseOrderVo.setPurchaseContractNo(planReleaseVo.getPurchaseContractNo());
            purchaseOrderVo.setSupplierCode(planReleaseVo.getSupplierCode());
            purchaseOrderVo.setDemandTime(planReleaseVo.getDemandTime());
            purchaseOrderVo.setMaterialCategory(procurementPlan.getMaterialCategory());
            purchaseOrderVo.setMaterialUnit(procurementPlan.getUnit());
            return purchaseOrderService.planConfirmation(purchaseOrderVo);

        } else if (planList.size() > 1) {
            //判断列表中物料编码是否一致（因为不同物料编码必然不同）
            StringBuilder ids = new StringBuilder();
            for (PlanVo plan : planList) {
                ids.append(plan.getPlanId()).append(",");
            }
            ids.deleteCharAt(ids.length() - 1);
            String s = ids.toString();
            List<ProcurementPlan> procurementPlans = procurementPlanMapper.selectList(new QueryWrapper<ProcurementPlan>().lambda().in(ProcurementPlan::getId, s));
            for (ProcurementPlan entity : procurementPlans) {
                if (entity.getStatus() != 5 && entity.getStatus() != 6) {
                    throw new GlobalException("存在状态不为待下达或者下达中的单据");
                }
                //将不同单据的下达量回传
                for (PlanVo planVo : planList) {
                    if (planVo.getPlanId() == entity.getId()) {
                        if (entity.getOrderQuantity() == 0) {
                            entity.setOrderQuantity(Double.parseDouble(planVo.getLowerWeight()));
                        } else {
                            BigDecimal bigDecimal = new BigDecimal(String.valueOf(entity.getOrderQuantity()));
                            BigDecimal bigDecimalPlanVo = new BigDecimal(planVo.getLowerWeight());
                            BigDecimal add = bigDecimal.add(bigDecimalPlanVo);
                            entity.setOrderQuantity(Double.parseDouble(add.toString()));
                        }

                    }
                }
                //根据下达重量修改单据状态
                BigDecimal surplusNum;
                if (entity.getSurplusNum() == null) {
                    surplusNum = new BigDecimal(entity.getPlanWeight()).subtract(new BigDecimal(planReleaseVo.getLowerWeightTotal()));
                } else {
                    surplusNum = new BigDecimal(entity.getSurplusNum()).subtract(new BigDecimal(planReleaseVo.getLowerWeightTotal()));
                }
                if (Integer.parseInt(surplusNum.toString()) > 0) {
                    entity.setStatus(6);
                } else {
                    entity.setStatus(7);
                }
                entity.setSurplusNum(surplusNum.toString());
            }

            //获取到列表中物料编码
            List<ProcurementPlanDto> procurementPlanDtos = planReleaseView(s);
            //物料编码
            String materialCode = procurementPlanDtos.get(0).getMaterialCode();
            StringBuilder stringBuilder = new StringBuilder();
            for (ProcurementPlan entity : procurementPlans) {
                stringBuilder.append(entity.getPurchaseNum()).append(",");
                boolean code = !entity.getMaterialCode().equals(materialCode);
                if (code) {
                    throw new GlobalException("不为同一种物料，不能进行合并下达");
                }
            }
            procurementPlanMapper.updateBatchById(procurementPlans);

            StringBuilder stringBuilder1 = stringBuilder.deleteCharAt(stringBuilder.length() - 1);
            //存入采购订单
            PurchaseOrderVo purchaseOrderVo = new PurchaseOrderVo();
            purchaseOrderVo.setMaterialCode(procurementPlans.get(0).getMaterialCode());
            purchaseOrderVo.setPurchaseNum(stringBuilder1.toString());
            purchaseOrderVo.setActualWeight(planReleaseVo.getLowerWeightTotal());
            purchaseOrderVo.setPlannedUnitPrice(planReleaseVo.getPlannedUnitPrice());
            purchaseOrderVo.setMaterialCode(procurementPlans.get(0).getMaterialCode());
            purchaseOrderVo.setPurchaseContractNo(planReleaseVo.getPurchaseContractNo());
            purchaseOrderVo.setMaterialCategory(procurementPlans.get(0).getMaterialCategory());
            purchaseOrderVo.setSupplierCode(planReleaseVo.getSupplierCode());
            purchaseOrderVo.setDemandTime(planReleaseVo.getDemandTime());
            return purchaseOrderService.planConfirmation(purchaseOrderVo);
        }
        return false;
    }
}
